package cc.xiaolv123.vvvdjToBaidu.util;

import cc.xiaolv123.vvvdjToBaidu.vo.BaiduwangpanFileVO;
import cc.xiaolv123.vvvdjToBaidu.vo.BaiduwangpanQuotaVO;
import cc.xiaolv123.vvvdjToBaidu.vo.BaiduwangpanUserInfoVO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.net.URLEncodeUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class BaiduwangpanUtil {
    @Value("${baidupan.client_id}")
    private String clientId;

    @Value("${baidupan.client_secret}")
    private String clientSecret;

    @Value("${baidupan.redirect_uri}")
    private String redirectUri;

    @Value("${baidupan.app_id}")
    private String appId;

    @Value("${baidupan.app_name}")
    private String appName;

    private static final String BAIDUPAN_TOKEN_KEY = "baiduwangpan:token";

    private static final String BAIDUPAN_REFRESH_TOKEN_KEY = "baiduwangpan:refreshtoken";

    @Autowired
    private RedisTemplate redisTemplate;

    public String code() {
        return "http://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectUri + "&scope=basic,netdisk&device_id=" + appId;
    }

    public boolean callback(String code) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code=" + code + "&client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri=" + redirectUri).method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "openapi.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            JSONObject object = JSON.parseObject(res);
            log.info("百度网盘===>验签===>{}", res);
            redisTemplate.opsForValue().set(BAIDUPAN_TOKEN_KEY, object.getString("access_token"), object.getLongValue("expires_in") - 5 * 60, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(BAIDUPAN_REFRESH_TOKEN_KEY, object.getString("refresh_token"));
            return true;
        }
        return false;
    }

    public boolean refreshToken() throws IOException {
        String refreshToken = redisTemplate.opsForValue().get(BAIDUPAN_REFRESH_TOKEN_KEY).toString();
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("https://openapi.baidu.com/oauth/2.0/token?grant_type=refresh_token&refresh_token=" + refreshToken + "&client_id=" + clientId + "&client_secret=" + clientSecret).method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "openapi.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            JSONObject object = JSON.parseObject(res);
            log.info("百度网盘===>刷新Token===>{}", res);
            redisTemplate.opsForValue().set(BAIDUPAN_TOKEN_KEY, object.getString("access_token"), object.getLongValue("expires_in") - 5 * 60, TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(BAIDUPAN_REFRESH_TOKEN_KEY, object.getString("refresh_token"));
            return true;
        }
        return false;
    }

    public String getToken() throws IOException {
        Object o = redisTemplate.opsForValue().get(BAIDUPAN_TOKEN_KEY);
        if (BeanUtil.isNotEmpty(o)) {
            return o.toString();
        } else {
            refreshToken();
            o = redisTemplate.opsForValue().get(BAIDUPAN_TOKEN_KEY);
            return o.toString();
        }
    }

    public BaiduwangpanUserInfoVO userInfo() throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("https://pan.baidu.com/rest/2.0/xpan/nas?method=uinfo&access_token=" + getToken()).method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>用户信息===>{}", res);
            BaiduwangpanUserInfoVO vo = JSON.parseObject(res, BaiduwangpanUserInfoVO.class);
            return vo;
        }
        return null;
    }

    public BaiduwangpanQuotaVO quota() throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("https://pan.baidu.com/api/quota?access_token=" + getToken() + "&checkfree=1&checkexpire=1").method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>容量===>{}", res);
            BaiduwangpanQuotaVO vo = JSON.parseObject(res, BaiduwangpanQuotaVO.class);
            return vo;
        }
        return null;
    }

    public BaiduwangpanFileVO filemetas(String fsid) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("http://pan.baidu.com/rest/2.0/xpan/multimedia?method=filemetas&access_token=" + getToken() + "&fsids=%5B" + fsid + "%5D&thumb=1&dlink=1&extra=1").method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>文件详情===>{}", res);
            BaiduwangpanFileVO vo = JSON.parseObject(res, BaiduwangpanFileVO.class);
            return vo;
        }
        return null;
    }

    public BaiduwangpanFileVO list(String dir) throws IOException {
        if (dir.startsWith("/apps")) {
            dir = URLEncodeUtil.encode(dir);
        } else {
            dir = URLEncodeUtil.encode("/apps/" + appName + dir);
        }
        System.out.println(dir);
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("https://pan.baidu.com/rest/2.0/xpan/file?method=list&dir=" + dir + "&order=time&start=0&limit=1000&web=1&folder=0&access_token=" + getToken() + "&desc=1").method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>文件列表===>{}", res);
            BaiduwangpanFileVO vo = JSON.parseObject(res, BaiduwangpanFileVO.class);
            return vo;
        }
        return null;
    }

    public BaiduwangpanFileVO listall(String dir) throws IOException {
        if (dir.startsWith("/apps")) {
            dir = URLEncodeUtil.encode(dir);
        } else {
            dir = URLEncodeUtil.encode("/apps/" + appName + dir);
        }
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("http://pan.baidu.com/rest/2.0/xpan/multimedia?method=listall&path=" + dir + "&access_token=" + getToken() + "&web=1&recursion=1&start=0&limit=1000&desc=1").method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").addHeader("Cookie", "BAIDUID=4E2AFC251E574812F6ECBE958B287490:FG=1").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>递归文件===>{}", res);
            BaiduwangpanFileVO vo = JSON.parseObject(res, BaiduwangpanFileVO.class);
            return vo;
        }
        return null;
    }

    public BaiduwangpanFileVO search(String dir, String key) throws IOException {
        if (dir.startsWith("/apps")) {
            dir = URLEncodeUtil.encode(dir);
        } else {
            dir = URLEncodeUtil.encode("/apps/" + appName + dir);
        }
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder().url("http://pan.baidu.com/rest/2.0/xpan/file?dir=" + dir + "&access_token=" + getToken() + "&web=1&recursion=1&page=1&num=500&method=search&key=" + key).method("GET", null).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").addHeader("Cookie", "BAIDUID=4E2AFC251E574812F6ECBE958B287490:FG=1").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>搜索文件===>{}", res);
            BaiduwangpanFileVO vo = JSON.parseObject(res, BaiduwangpanFileVO.class);
            return vo;
        }
        return null;
    }

    public boolean rename(String path, String newname) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "async=0&filelist=[{\"path\":\"" + path + "\",\"newname\":\"/" + newname + "\"}]&ondup=overwrite");
        Request request = new Request.Builder().url("http://pan.baidu.com/rest/2.0/xpan/file?method=filemanager&access_token=" + getToken() + "&opera=rename").method("POST", body).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").addHeader("Content-Type", "application/x-www-form-urlencoded").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>重命名===>{}", res);
            JSONObject object = JSON.parseObject(res);
            int errno = object.getIntValue("errno");
            return errno == 0;
        }
        return false;
    }

    public boolean copy(String path, String dest, String newname) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "async=0&filelist=[{\"path\":\"" + path + "\",\"dest\":\"" + dest + "\",\"newname\":\"" + newname + "\",\"ondup\":\"overwrite\"}]");
        Request request = new Request.Builder().url("http://pan.baidu.com/rest/2.0/xpan/file?method=filemanager&access_token=" + getToken() + "&opera=copy").method("POST", body).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").addHeader("Content-Type", "application/x-www-form-urlencoded").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>复制===>{}", res);
            JSONObject object = JSON.parseObject(res);
            int errno = object.getIntValue("errno");
            return errno == 0;
        }
        return false;
    }

    public boolean move(String path, String dest, String newname) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "async=0&filelist=[{\"path\":\"" + path + "\",\"dest\":\"" + dest + "\",\"newname\":\"" + newname + "\",\"ondup\":\"overwrite\"}]");
        Request request = new Request.Builder().url("http://pan.baidu.com/rest/2.0/xpan/file?method=filemanager&access_token=" + getToken() + "&opera=move").method("POST", body).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").addHeader("Content-Type", "application/x-www-form-urlencoded").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>移动===>{}", res);
            JSONObject object = JSON.parseObject(res);
            int errno = object.getIntValue("errno");
            return errno == 0;
        }
        return false;
    }

    public boolean delete(String path) throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        path = URLEncodeUtil.encode(path);
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "async=0&filelist=[\"" + path + "\"]");
        Request request = new Request.Builder().url("http://pan.baidu.com/rest/2.0/xpan/file?method=filemanager&access_token=" + getToken() + "&opera=delete").method("POST", body).addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").addHeader("Content-Type", "application/x-www-form-urlencoded").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>删除===>{}", res);
            JSONObject object = JSON.parseObject(res);
            int errno = object.getIntValue("errno");
            return errno == 0;
        }
        return false;
    }

    public boolean upload(String localPath, String baiduPath, String fileName) throws IOException {
        if ("/".equals(baiduPath)) {
            baiduPath = URLEncodeUtil.encode("/apps/" + appName + "/" + fileName);
        } else {
            baiduPath = URLEncodeUtil.encode("/apps/" + appName + "/" + baiduPath + "/" + fileName);
        }
        OkHttpClient client = new OkHttpClient.Builder().connectTimeout(999, TimeUnit.SECONDS).pingInterval(5, TimeUnit.SECONDS).readTimeout(999, TimeUnit.SECONDS).writeTimeout(999, TimeUnit.SECONDS).build();
        File file = new File(localPath + "/" + fileName);
        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file)).build();
        Request request = new Request.Builder().url("https://d.pcs.baidu.com/rest/2.0/pcs/file?method=upload&access_token=" + getToken() + "&path=" + baiduPath + "&ondup=overwrite").method("POST", body).addHeader("User-Agent", "pan.baidu.com").addHeader("Accept", "*/*").addHeader("Host", "d.pcs.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>上传===>{}", res);
            JSONObject object = JSON.parseObject(res);
            int errno = object.getIntValue("errno");
            return errno == 0;
        }
        return false;
    }

    public boolean mkdir(String dir) throws IOException {
        if ("/".equals(dir)) {
            dir = URLEncodeUtil.encode("/apps/" + appName + "/");
        } else {
            dir = URLEncodeUtil.encode("/apps/" + appName + "/" + dir);
        }
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "path=" + dir + "&isdir=1&rtype=0");
        Request request = new Request.Builder().url("https://pan.baidu.com/rest/2.0/xpan/file?method=create&access_token=" + getToken()).method("POST", body).addHeader("Content-Type", "application/x-www-form-urlencoded").addHeader("Accept", "*/*").addHeader("Host", "pan.baidu.com").addHeader("Connection", "keep-alive").build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("百度网盘===>创建文件夹===>{}", res);
            JSONObject object = JSON.parseObject(res);
            int errno = object.getIntValue("errno");
            return errno == 0;
        }
        return false;
    }

}
